/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package projectiteu;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Set;

/**
 *
 * @author floroza
 */
public class StandardLib {
    //TODO: Static list of vars or File input
    protected static String[] currentVars;
    private final int EOF = -1;
    //c++ to c#
    private HashMap<String, String> codeList;
    final StandardIO sio = new StandardIO();
    
    //Stores global vars
    private LinkedList glob = new LinkedList();
    //test vars
    //private String[]  testVars= {"int" , "float"};
    public StandardLib(){
        //currentVars = testVars;
        initMap();
    }
    
    //Adds spacing to characters to tokenize words
    private String codeCleaner(String input){
        input = input.replaceAll("[(]", " ( ");
        input = input.replaceAll("[)]", " ) ");
        input = input.replaceAll("[{]", " { ");
        input = input.replaceAll("[}]", " } ");
        input = input.replaceAll("[+]", " + ");
        input = input.replaceAll("[-]", " - ");
        input = input.replaceAll("[*]", " * ");
        input = input.replaceAll("[/]", " / ");
        //input = input.replaceAll("[;]", " ; ");
        //input = input.replaceAll("[<]", " < ");
        input = input.replaceAll("[>]", " > ");
        //input = input.replaceAll("[=]", " = ");
        input = input.replaceAll("[,]", " , ");
        return input;
    }
    //get code in int Main function
    private String getMainCode(String input){
        String output = "";
        boolean paren = false;
        int oparen = 0, cparen = 0;
        for(int i=0;i<input.length();i++){
            if(input.charAt(i)=='{'){
                oparen++;
                paren = true;
            }
            if(paren){
                output += input.charAt(i);
            }
            if(input.charAt(i)=='}'){
                cparen++;
                if((oparen+cparen)%2==0){
                    paren = false;
                }
            }
        }
        return output;
    }
    //Determine if it's a variable
    private String getSimpleVars(String x, String y){
        String output = "";
        for(String dmagic: currentVars)
            if(x.equalsIgnoreCase(dmagic))
                output = x + " " + y;
        return output;
    }
    //Core function
    //this shit makes c++ to c#
    //still need to do the code that checks on what includes is
    //new StandardLib().convertCode(jtextareas input here);
    public String convertCode(String input){
        String header = "class ITEUproj\n"
                + "{\n"
                + "static int Main()";
        
        String output = "";
        input = getMainCode(input);
        
        input = codeCleaner(input);
        String outArr[] = input.split("\n");
        
        
        for(String inputv2:outArr){
            if(inputv2.contains("cout")) {
                //System.out.println("LOLLLOO");
                output += sio.convertOutputToC(inputv2)+"\n";
            } else if(inputv2.contains("cin")) {
                output += sio.convertInputToC(inputv2)+"\n";
            } else if(check(inputv2)) {
                sio.initialize(inputv2);
                output += inputv2+"\n";
            } else {
                output += translator(inputv2)+"\n";
            }
        }
       // System.out.println(outpoot);
       // System.out.println(output);
        output = header + output + "\n}";
        return output;
    }
    
    private boolean check(String input) {
        String[] dttyps = {"int", "short", "long", "double", "float", "byte", "bool", "string", "char"};
        for(String x : dttyps) {
            if(input.contains(x)) {
                return true;
            }
        }
        return false;
    }
    
    //converts the C++ to C# variables
    private String translator(String input){
        String output = "";
        
        
            String[] outputArr = input.split("\\s+");
    //        Set<String> keys = codeList.keySet();
    //        String[] arrKeys = new String[keys.size()];
    //        keys.toArray(arrKeys);
    //        ArrayList<String> vls = new ArrayList<>(codeList.values());

            for(int i=0;i<outputArr.length;i++){
                //System.out.println(outputArr[i]);
                if(codeList.containsKey(outputArr[i]))
                    output += codeList.get(outputArr[i]).toString()+" ";
                else
                    output += outputArr[i]+" ";
            }
        
        
        //System.out.println("Output: " + output);
        return output;
    }
    //Initializes the code list at instance
    private void initMap(){
        codeList = new HashMap<>();
        try{
            String out[] = gotString().split("\n");
            for(String tae: out) {
                String[] tmp = tae.trim().split("\\s+");
                codeList.put(tmp[0], tmp[1]);
                //System.out.println(tmp[0]+" "+tmp[1]);
            }
            
        }catch(Exception e) {
            System.out.println(e.getMessage());
        }
    }
    
    //Reads the variables from file and outputs as string
    private String gotString()throws Exception{
        BufferedReader br = null;
        String output = "";
        int sCurrentchar;
        br = new BufferedReader(new FileReader("src/corpora"));
        while ((sCurrentchar = br.read()) != EOF)
                    output += (char)sCurrentchar;
        br.close();
        return output;
    }
    /*Don't really know why I did all of the below
     * This was never really part of the scope D:
     * 
    */
    //Gets global variables
    //Lazy function
    protected String[] getGlobal(String input){
        getFunctions(input);
        String[] output = listToString(glob.toArray());
        return output;
    }
    //Gets functions from code input
    protected String[] getFunctions(String input){
        
        //LinkedList for dynamic String Array
        LinkedList funcs2 = new LinkedList();
        input = codeCleaner(input);
        String[] magic = input.split("\\s+");
        try{
            boolean first = true;
            boolean truefunc= true;
            int count = 0 , caunt = 0;
            
            for(int i=1;i<magic.length;i++){
                //System.out.println(i);
                if(first){
                    if(!getSimpleVars(magic[i-1],magic[i]).isEmpty()){
                        int xcount=0,ycount=0,ocount=0;
                        
                        for(int ret = i;ret<magic.length;ret++){
                            //System.out.println(magic[ret]);
                            if(magic[ret].equalsIgnoreCase("(")){
                                xcount++;
                            }
                            
                            
                            if(xcount==1&&ocount==2){
                                funcs2.add(getSimpleVars(magic[i-1],magic[i]));
                                first = false;
                                ret = magic.length;
                            }
                            else if(ocount>=3){
                                //this gets the variable when it realizes it's not a function
                                glob.add(getSimpleVars(magic[i-1],magic[i]));
                                truefunc=false;
                                ret = magic.length;
                            }
                            ocount++;
                            
                                
                        }
                        
                        
                    }
                }
                else{
                    
                    if(magic[i].equalsIgnoreCase("{")){
                        count++;
                    }
                    if(magic[i].equalsIgnoreCase("}")){
                        caunt++;
                    }
                }
                if(count == caunt && (count!=0||caunt!=0)){
                    //System.out.print("PING!");
                        count = 0;
                        caunt = 0;
                        first = true;
                }
                //System.out.print("Count is:"+count+" and Caunt:"+caunt+"\n");
            }
        }
        catch(Exception e){
           
        }
        String[] output = listToString(funcs2.toArray());
        return output;
    }
    //Turns object array into String Array
    private String[] listToString(Object[] in){
        String[] out = new String[in.length];
        for(int i=0;i<out.length;i++){
            out[i] = in[i].toString();
        }
        return out;
    }
}